第 16 屆 iThome 鐵人賽 (2023)
{%hackmd BJrTq20hE %}
# 1.features (數字影像的特徵值) 資料前處理
# 先將 image 以 reshape 轉換為二維 ndarray 並進行 normalization (Feature scaling):
x_Train = X_train_image.reshape(60000, 28*28).astype('float32')
x_Test = X_test_image.reshape(10000, 28*28).astype('float32')
print("\t[Info] xTrain: %s" % (str(x_Train.shape)))
print("\t[Info] xTest: %s" % (str(x_Test.shape)))
# Normalization
x_Train_norm = x_Train/255
x_Test_norm = x_Test/255
輸出:
>>>[Info] xTrain: (60000, 784)
>>>[Info] xTest: (10000, 784)
# 2.labels (影像數字真實的值) 資料前處理
y_TrainOneHot = np_utils.to_categorical(y_train_label)
# 將 training 的 label 進行 one-hot encoding
y_TestOneHot = np_utils.to_categorical(y_test_label)
# 將測試的 labels 進行 one-hot encoding
# 檢視 training labels 第一個 label 的值
print (y_train_label[0])
# 檢視第一個 label 在 one-hot encoding 後的結果, 會在第六個位置上為 1, 其他位置上為 0
print(y_TrainOneHot[:1])
輸出:
>>>5
>>>[[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]]
label 標籤欄位原本是 0-9 數字, 而為了配合 Keras 的資料格式, 必須進行 One-hot-encoding 將之轉換為 10 個 0 或 1 的組合, 例如數字 7 經過 One-hot encoding 轉換後是 0000001000, 正好對應到輸出層的 10 個神經元.
from keras.models import Sequential
from keras.layers import Dense
model = Sequential() # Build Linear Model
model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation='relu')) # Add Input/hidden layer
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax')) # Add Hidden/output layer
print("\t[Info] Model summary:")
model.summary()
print("")
輸出:
# 在訓練模型之前, 我們必須先使用 compile 方法, 對訓練模型進行設定
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 2.開始訓練
train_history = model.fit(x=x_Train_norm, y=y_TrainOneHot, validation_split=0.2, epochs=10, batch_size=200, verbose=2)
上面訓練過程會儲存於 train_history 變數中:
# 3.建立 show_train_history 顯示訓練過程
# 訓練步驟會將每一個訓練週期的 accuracy 與 loss 記錄在 train_history 變數
# 讀取 train_history 以圖表顯示訓練過程:
import matplotlib.pyplot as plt
def show_train_history(train_history,train,validation):
plt.plot(train_history.history[train])
plt.plot(train_history.history[validation])
plt.title('Train history')
plt.ylabel('train')
plt.xlabel('epoch')
# 設置圖例在左上角
plt.legend(['train','validation'],loc='upper left')
plt.show()
show_train_history(train_history,'accuracy','val_accuracy')
show_train_history(train_history,'loss','val_loss')
如果 “accuracy 訓練的準確率” 一直提升,但是 “val_accuracy 的準確率” 卻一直沒有增加,可能是 Overfitting 的現象.
在完成所有 (epoch) 訓練週期後,在後面還會使用測試資料來評估模型準確率, 這是另外一組獨立的資料,所以計算準確率會更客觀.
總共執行 10 個 Epoch 訓練週期, 發現:
不論訓練與驗證, 誤差越來越低.
在 Epoch 訓練後期, “loss 訓練的誤差” 比 “val_loss 驗證的誤差” 小.